package SG3D

import (
	//. "SGEngine"
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var (
	ModelReader meshreader
)

type meshreader struct {
	CurType string
}

func (m *meshreader) LoadObj(FileName string) *Model {
	fi, err := os.Open(FileName)
	if err != nil {
		panic(err)
		return nil
	}
	defer fi.Close()

	RM := new(Model)
	rf := bufio.NewReader(fi)
	for {
		linstr, err := rf.ReadString('\n')
		if err != nil {
			break
		}
		m._Obj_ReadLine(linstr, RM)
	}
	RM.BindBuffer()
	return RM
}

func (m *meshreader) _Obj_ReadLine(linstr string, RM *Model) {
	linstr = strings.Trim(linstr, "\r\n")
	if linstr[0] == '#' {
		return
	}
	StrArr := strings.Split(linstr, " ")
	str0 := StrArr[0]
	if str0 == "mtllib" {
		return
	}
	if str0 == "g" {
		mesh := NewMesh()
		mesh.Name = StrArr[1]
		RM.Meshs = append(RM.Meshs, mesh)
	}
	CurMesh := RM.Meshs[len(RM.Meshs)-1]
	if str0 == "v" {
		v1, _ := strconv.ParseFloat(StrArr[1], 32)
		v2, _ := strconv.ParseFloat(StrArr[2], 32)
		v3, _ := strconv.ParseFloat(StrArr[3], 32)
		CurMesh.V = append(CurMesh.V, float32(v1))
		CurMesh.V = append(CurMesh.V, float32(v2))
		CurMesh.V = append(CurMesh.V, float32(v3))
		//fmt.Print(CurMesh.V)
	}
	if str0 == "vt" {
		v1, _ := strconv.ParseFloat(StrArr[1], 32)
		v2, _ := strconv.ParseFloat(StrArr[2], 32)
		CurMesh.UV = append(CurMesh.UV, float32(v1))
		CurMesh.UV = append(CurMesh.UV, float32(v2))
	}
	if str0 == "vn" {
		v1, _ := strconv.ParseFloat(StrArr[1], 32)
		v2, _ := strconv.ParseFloat(StrArr[2], 32)
		v3, _ := strconv.ParseFloat(StrArr[3], 32)
		CurMesh.Vn = append(CurMesh.Vn, float32(v1))
		CurMesh.Vn = append(CurMesh.Vn, float32(v2))
		CurMesh.Vn = append(CurMesh.Vn, float32(v3))
	}
	if str0 == "f" {

		v1Strs := strings.Trim(StrArr[2], " ")
		v2Strs := strings.Trim(StrArr[3], " ")
		v3Strs := strings.Trim(StrArr[4], " ")

		fmt.Println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
		fmt.Println(linstr)
		fmt.Println("@" + v1Strs + "@")
		fmt.Println("@" + v2Strs + "@")
		fmt.Println("@" + v3Strs + "@")
		fmt.Println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
		V1Arr := strings.Split(v1Strs, "/")
		V2Arr := strings.Split(v2Strs, "/")
		V3Arr := strings.Split(v3Strs, "/")

		Vi1, _ := strconv.ParseInt(V1Arr[0], 10, 32)
		Vi2, _ := strconv.ParseInt(V2Arr[0], 10, 32)
		Vi3, _ := strconv.ParseInt(V3Arr[0], 10, 32)
		CurMesh.Inc = append(CurMesh.Inc, int(Vi1))
		CurMesh.Inc = append(CurMesh.Inc, int(Vi2))
		CurMesh.Inc = append(CurMesh.Inc, int(Vi3))
	}

}

func (m *meshreader) LoadSGM(path string) *Model {
	fi, err := os.Open(path)
	if err != nil {
		panic(err)
		return nil
	}
	defer fi.Close()

	RM := new(Model)
	rf := bufio.NewReader(fi)
	for {
		linstr, err := rf.ReadString('\n')
		if err != nil {
			break
		}
		m._SGM_ReadLine(linstr, RM)
	}
	RM.BindBuffer()

	return RM
}

func (m *meshreader) _SGM_ReadLine(linstr string, RM *Model) {
	linstr = strings.Trim(linstr, "\n")
	linstr = strings.Trim(linstr, "\r")
	linstr = strings.Trim(linstr, " ")
	linArr := strings.Split(linstr, " ")
	var CurMesh *Mesh
	if RM.Meshs != nil {
		CurMesh = RM.Meshs[len(RM.Meshs)-1]
	}
	if m.CurType == "V" {
		linArr[0] = strings.Trim(linArr[0], " ")
		if linArr[0] != "I" && linArr[0] != "M" && linArr[0] != "UV" && linArr[0] != "V" {
			linArr[1] = strings.Trim(linArr[1], " ")
			linArr[2] = strings.Trim(linArr[2], " ")
			v1, _ := strconv.ParseFloat(linArr[0], 32)
			v2, _ := strconv.ParseFloat(linArr[1], 32)
			v3, _ := strconv.ParseFloat(linArr[2], 32)
			if CurMesh != nil {
				CurMesh.V[CurMesh.Vsize] = float32(v1)
				CurMesh.Vsize += 1
				CurMesh.V[CurMesh.Vsize] = float32(v2)
				CurMesh.Vsize += 1
				CurMesh.V[CurMesh.Vsize] = float32(v3)
				CurMesh.Vsize += 1
			}
		}
	}

	if m.CurType == "UV" {
		linArr[0] = strings.Trim(linArr[0], " ")
		if linArr[0] != "I" && linArr[0] != "M" && linArr[0] != "UV" && linArr[0] != "V" {
			for _, V := range linArr {
				V = strings.Trim(V, "\n")
				V = strings.Trim(V, " ")
				v1, _ := strconv.ParseFloat(V, 32)
				CurMesh.UV[CurMesh.UVSize] = float32(v1)
				CurMesh.UVSize += 1
			}
		}
	}

	if m.CurType == "I" {
		linArr[0] = strings.Trim(linArr[0], " ")
		if linArr[0] != "I" && linArr[0] != "M" && linArr[0] != "UV" && linArr[0] != "V" {

			for _, V := range linArr {
				V = strings.Trim(V, "\n")
				V = strings.Trim(V, " ")
				Vi1, _ := strconv.ParseInt(V, 10, 32)
				fmt.Println("-" + strconv.Itoa(CurMesh.Isize) + "-")
				fmt.Println("@" + V + "@")
				CurMesh.Inc[CurMesh.Isize] = int(Vi1)
				CurMesh.Isize += 1

				//fmt.Println("@-" + strconv.Itoa(len(CurMesh.Inc)) + "-@")

			}
		}
	}

	if linArr[0] == "M" {
		m.CurType = "M"
		mesh := NewMesh()
		mesh.Name = linArr[1]
		RM.Meshs = append(RM.Meshs, mesh)
	}

	if linArr[0] == "V" {
		m.CurType = "V"
		if CurMesh.V == nil {

			Count, err := strconv.Atoi(linArr[1])
			if err != nil {
				fmt.Println(err)
			}
			CurMesh.V = make([]float32, Count*3)
		}
	}
	if linArr[0] == "I" {
		m.CurType = "I"
		if CurMesh.Inc == nil {
			Count, _ := strconv.Atoi(linArr[1])
			CurMesh.Inc = make([]int, Count*3)
			fmt.Println("Inc_" + strconv.Itoa(Count*3) + "_Inc")
		}
	}
	if linArr[0] == "UV" {
		if CurMesh.UV == nil {
			fmt.Println("New UV")
			m.CurType = "UV"
			Count, _ := strconv.Atoi(linArr[1])
			CurMesh.UV = make([]float32, Count)
		}
	}

}
